home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 April: Mac OS SDK / Dev.CD Apr 00 SDK1.toast / Development Kits / Mac OS / Open Transport 1.3 / Open Transport SDK / Open Tpt Client Developer / Samples / AppleTalk / DDPSample.cp < prev    next >
Encoding:
Text File  |  1998-04-30  |  27.5 KB  |  1,232 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        DDPSample.cp
  3.  
  4.     Contains:    Sample program for demonstration of DDP Endpoints, NBP (via TMapper),
  5.                 and ZIP (via TAppleTalkServices).
  6.  
  7.     Copyright:    © 1991-1996 by Apple Computer, Inc., all rights reserved.
  8.  
  9. */
  10.  
  11. #ifndef __OPENTPTGLOBALNEW__
  12. #include <OpenTptGlobalNew.h>
  13. #endif
  14. #ifndef __OPENTPTAPPLETALK__
  15. #include <OpenTptAppleTalk.h>
  16. #endif
  17. #ifndef __ATALKSAMPLEUTILS__
  18. #include "ATalkSampleUtils.h"
  19. #endif
  20. #ifndef __STDIO__
  21. #include <stdio.h>
  22. #endif
  23. #ifndef __EVENTS__
  24. #include <Events.h>
  25. #endif
  26.  
  27. OSStatus        gErrorAckMsg    = kOTNoError;
  28. void*            gOKAckMsg        = NULL;
  29. size_t            gLkUpReplies;
  30. size_t            gOurAddrLen;
  31. UInt8            gOurAddr[50];
  32. long            gNotifyFlag;
  33. OTEventCode        gNotifyCode;
  34. OSStatus        gNotifyErr;
  35. void*            gNotifyCookie;
  36. RgnHandle        gRgn;
  37.  
  38. const size_t    kMaxReplyBufLen = (578 * 8) + 4;
  39.  
  40. static UInt8    incomingReply[kMaxReplyBufLen];
  41.  
  42.  
  43. /*******************************************************************************
  44. ** HandleEndpointEvents
  45. ********************************************************************************/
  46.  
  47. pascal void HandleEndpointEvents(void* contextPtr, OTEventCode code,
  48.                                        OTResult result, void* it)
  49. {
  50.     if ( contextPtr != &gNotifyFlag )
  51.         DebugStr("\pHandleEndpointEvents: The contextPtr is not correct");
  52.     else
  53.         *((unsigned long*)contextPtr) = (code << 16) + result;
  54.  
  55.     if ( code == T_MEMORYRELEASED )
  56.     {
  57.         gOKAckMsg = it;
  58.     }
  59.     else
  60.     {
  61.         gNotifyCode        = code;
  62.         gNotifyErr        = (OSStatus)result;
  63.         gNotifyCookie    = it;
  64.     }
  65. }
  66.  
  67. /*******************************************************************************
  68. ** HandleMapperEvents TMapper (NBP) Event Handling
  69. ********************************************************************************/
  70.  
  71. pascal void HandleMapperEvents(void*, OTEventCode event, OTResult result,
  72.                                      void* cookie)
  73. {
  74.     switch ( event )
  75.     {
  76.         case T_LKUPNAMERESULT:        // intermediate result notification
  77.             break;
  78.         
  79.         case T_LKUPNAMECOMPLETE:
  80.         
  81.             if ( result != kOTNoError )
  82.                 gErrorAckMsg = (OSStatus)result;
  83.             gOKAckMsg = cookie;
  84.             break;
  85.             
  86.         case T_REGNAMECOMPLETE:
  87.             if ( result != kOTNoError )
  88.             {
  89.                 gErrorAckMsg = (OSStatus)result;
  90.             }
  91.             else
  92.             {
  93.                 gOKAckMsg = (void*) 1;
  94.             }
  95.             break;
  96.             
  97.         case T_DELNAMECOMPLETE:
  98.             if ( result != kOTNoError )
  99.             {
  100.                 gErrorAckMsg = (OSStatus)result;
  101.             }
  102.             else
  103.             {
  104.                 gOKAckMsg = (void*) 1;
  105.             }
  106.             break;
  107.             
  108.         default:
  109.             DebugStr("\pHandleMapperEvents: Unexpected Event!;g");
  110.             break;
  111.     }
  112. }
  113.  
  114. /*******************************************************************************
  115. ** HandleServicesEvents            AppleTalkSvc (ZIP) Event Handling
  116. ********************************************************************************/
  117.  
  118. pascal void HandleServicesEvents(void*, OTEventCode event, OTResult result,
  119.                                        void* cookie)
  120. {
  121.     switch ( event )
  122.     {
  123.         case T_GETMYZONECOMPLETE:
  124.             if ( result != kOTNoError )
  125.             {
  126.                 gErrorAckMsg = (OSStatus)result;
  127.                 break;
  128.             }
  129.             gOKAckMsg = cookie;
  130.             break;
  131.             
  132.         case T_GETLOCALZONESCOMPLETE:
  133.             if ( result != kOTNoError )
  134.             {
  135.                 gErrorAckMsg = (OSStatus)result;
  136.                 break;
  137.             }
  138.             gOKAckMsg = cookie;
  139.             break;
  140.             
  141.         case T_GETZONELISTCOMPLETE:
  142.             if ( result != kOTNoError )
  143.             {
  144.                 gErrorAckMsg = (OSStatus)result;
  145.                 break;
  146.             }
  147.             gOKAckMsg = cookie;
  148.             break;
  149.             
  150.         case T_GETATALKINFOCOMPLETE:
  151.             if ( result != kOTNoError )
  152.             {
  153.                 gErrorAckMsg = (OSStatus)result;
  154.                 break;
  155.             }
  156.             gOKAckMsg = cookie;
  157.             break;
  158.             
  159.         default:
  160.             DebugStr("\pHandleServicesEvents: Unexpected Event!;g");
  161.             break;
  162.     }
  163. }
  164.  
  165. /*    -------------------------------------------------------------------------
  166.                     DDP Demonstration routines
  167.     ------------------------------------------------------------------------- */
  168.  
  169. /*******************************************************************************
  170. ** BindDDPEndpoint
  171. ********************************************************************************/
  172.  
  173. OSStatus BindDDPEndpoint(EndpointRef ep)
  174. {
  175.     OSStatus err;
  176.     
  177.     //
  178.     // Request socket $54 and DDP $4
  179.     //
  180.     DDPAddress reqAddr;
  181.     reqAddr.Init(0, 0, 0x54, 4);        // Source address & type
  182.     
  183.     TBind                    req;
  184.     
  185.     req.addr.buf    = (UInt8*)&reqAddr;
  186.     req.addr.len    = kDDPAddressLength;
  187.     req.qlen        = 0;
  188.     
  189.     DDPAddress retAddr;
  190.     TBind                    ret;
  191.     
  192.     ret.addr.buf    = (UInt8*)&retAddr;
  193.     ret.addr.maxlen    = sizeof(retAddr);
  194.     
  195.     fprintf(stderr, "Binding DDP endpoint\n");
  196.     err = OTBind(ep, &req, &ret);
  197.     if ( err != kOTNoError )
  198.     {
  199.         fprintf(stderr, "Bind returns %d\n", err);
  200.         return err;
  201.     }
  202.     ShowDDPAddress(&retAddr);
  203.  
  204.     fprintf(stderr, "\nAfter Bind, ");
  205.     ShowEndpointState(ep, "");
  206.     
  207.     return err;
  208. }
  209.  
  210. /*******************************************************************************
  211. ** ReadData
  212. ********************************************************************************/
  213.  
  214. OSStatus ReadData(EndpointRef ep)
  215. {
  216.     OTFlags            flags = 0;
  217.     DDPAddress        theDest;
  218.     UInt8            buf[200];
  219.     TUnitData        theData;
  220.     
  221.     theData.udata.buf    = buf;
  222.     theData.udata.maxlen= sizeof(buf);
  223.     theData.addr.buf    = (UInt8*)&theDest;
  224.     theData.addr.maxlen    = sizeof(theDest);
  225.     theData.opt.maxlen    = 0;
  226.     
  227.     OSStatus err = OTRcvUData(ep, &theData, &flags);
  228.     
  229.     if ( err != kOTNoError )
  230.     {
  231.         fprintf(stderr, "RcvUData() returns %d", err);
  232.         if (err == kOTNoDataErr)
  233.             fprintf(stderr, " (kOTNoDataErr)\n");
  234.         else
  235.             fprintf(stderr, "\n");
  236.     }        
  237.         
  238.     if ( err != kOTNoError )
  239.         return err;
  240.         
  241.     size_t numbytes = theData.udata.len;
  242.     fprintf(stderr, "flags = %08lx; read %d bytes: ", flags, numbytes);
  243.     if ( numbytes > 10 )
  244.         numbytes = 10;
  245.     
  246.     for (size_t i = 0 ; i < numbytes ; i++)
  247.         fprintf(stderr, "%02x ", buf[i]);
  248.     fprintf(stderr, "\n");
  249.     
  250.     return err;
  251. }
  252.  
  253. /*******************************************************************************
  254. ** DoSend
  255. ********************************************************************************/
  256.  
  257. OSStatus DoSend(EndpointRef ep)
  258. {
  259.     DDPAddress    theDest;                    // Who to send to
  260.     TUnitData    unitData;                    // To pass to SndUData
  261.     OSStatus    err;
  262.     
  263.     static unsigned char    theBuffer[] = "\x01Hello";    // What to send them
  264.  
  265.     theDest.Init(0, 0xff, 4, 4);
  266.     
  267.     unitData.udata.buf    = theBuffer;
  268.     unitData.udata.len    = 6;                            // Initialize data
  269.     unitData.addr.buf    = (UInt8*)&theDest;
  270.     unitData.addr.len    = kDDPAddressLength;            // Initialize address part
  271.     unitData.opt.len    = 0;                            // No options
  272.  
  273.     OTAckSends(ep);
  274.     gOKAckMsg    = NULL;
  275.     gNotifyCode = 0;
  276.     
  277.     err = OTSndUData(ep, &unitData);
  278.     
  279.     OTDontAckSends(ep);
  280.     if ( err != kOTNoError )
  281.     {
  282.         fprintf(stderr, "SndUData() returns %d\n", err);
  283.     }
  284.     else
  285.     {
  286.         //
  287.         // It's very important that we read the data while we are waiting for the "ack send" to complete.
  288.         // DDP can use our own message to reply to us, and if we don't "read" the message, the "ackSend"
  289.         // will never complete.
  290.         //
  291.         while ( gOKAckMsg == NULL )
  292.         {
  293.             if ( gNotifyCode == T_DATA )
  294.             {
  295.                 gNotifyCode = 0;
  296.                 while ( ReadData(ep) != kOTNoDataErr )
  297.                     OTIdle();
  298.             }
  299.             OTIdle();
  300.         }
  301.         if ( gOKAckMsg != theBuffer )
  302.         {
  303.             fprintf(stderr, "ERROR: DoSend - the T_SENDCOMPLETE cookie was not my buffer (%08X)\n", gNotifyCookie);
  304.         }
  305.     }
  306.     return err;
  307. }
  308.  
  309. /*    -------------------------------------------------------------------------
  310.                     NBP Demonstration routines
  311.     ------------------------------------------------------------------------- */
  312.  
  313. /*******************************************************************************
  314. ** DoSendLkUpReq
  315. ********************************************************************************/
  316.  
  317. OSStatus DoSendLkUpReq(size_t count, MapperRef epm)
  318. {
  319.     OSStatus err = kOTNoError;
  320.  
  321.     static char stuff[] = "=:Workstation";        // pattern we want to look up
  322.  
  323.     TLookupRequest    theRequest;
  324.     
  325.     theRequest.name.buf    = (UInt8*)stuff;
  326.     theRequest.name.len    = OTStrLength(stuff);
  327.     theRequest.addr.len    = 0;
  328.     theRequest.maxcnt    = count;
  329.     theRequest.timeout    = 0;        // Default timeout
  330.  
  331.     gErrorAckMsg = kOTNoError;
  332.     gOKAckMsg = NULL;
  333.  
  334.     fprintf(stderr, "Looking for %d names that match \"%s\"\n", count, stuff);
  335.     
  336.     do
  337.     {
  338.         TLookupReply* theReply = new TLookupReply;
  339.         if ( theReply == NULL )
  340.         {
  341.             err = kENOMEMErr;
  342.             break;
  343.         }
  344.         theReply->names.buf        = incomingReply;
  345.         theReply->names.maxlen    = kMaxReplyBufLen;
  346.         
  347.         err = OTLookupName(epm, &theRequest, theReply);
  348.     
  349.         if ( err != kOTNoError )
  350.         {
  351.             fprintf(stderr, "DoSendLkUpReq:LookupName returns %d\n", err);
  352.         }
  353.         else
  354.         {
  355.             err = kOTNoError;
  356.         }
  357.  
  358.     } while ( false );
  359.     return err;
  360. }
  361.  
  362. /*******************************************************************************
  363. ** DoReadLkUpReplies
  364. ********************************************************************************/
  365.  
  366. void DoReadLkUpReplies()
  367. {
  368.     long            datacnt = 0;
  369.     TLookupReply*    reply;
  370.     UInt8*            ptr;
  371.  
  372.     while ( gOKAckMsg == NULL && gErrorAckMsg == kOTNoError )
  373.         OTIdle();
  374.         
  375.     reply = (TLookupReply*)gOKAckMsg;
  376.     
  377.     if ( gErrorAckMsg != kOTNoError )
  378.     {    
  379.         fprintf(stderr, "Lookup completed with error %d\n", gErrorAckMsg);
  380.     }
  381.  
  382.     if ( gErrorAckMsg == kOTNoError || gErrorAckMsg == kOTBufferOverflowErr )
  383.     {
  384.         ptr = reply->names.buf;
  385.  
  386.         long linct = reply->rspcount;
  387.  
  388.         while ( linct-- )
  389.         {
  390.             UInt16 addrLength    = ((short*)ptr)[0];
  391.             UInt16 nameLength    = ((short*)ptr)[1];
  392.  
  393.             ptr += 2*sizeof(short);
  394.             
  395.             if ( addrLength != kDDPAddressLength || ((DDPAddress*)ptr)->GetAddressType() != AF_ATALK_DDP)
  396.             {
  397.                 fprintf(stderr, "Unexpected Address");
  398.             }
  399.             else
  400.             {
  401.                 ShowDDPAddress((DDPAddress*)ptr);            // show the address
  402.             }
  403.             ptr += addrLength;
  404.             fprintf(stderr, " = ");
  405.  
  406.             fprintf(stderr, "%*.*s", nameLength, nameLength, ptr);
  407.  
  408.             fprintf(stderr, "\n");
  409.  
  410.             ptr += nameLength;
  411.             if ( (addrLength + nameLength) & 3 )                                // pad to 4 byte alignment
  412.             {
  413.                 ptr += (4 - ((addrLength + nameLength) & 3));
  414.             }
  415.         }
  416.         fprintf(stderr, "Reply %2d: %3d bytes %3d names ", ++datacnt,
  417.                             reply->names.len, reply->rspcount);
  418.         fprintf(stderr, "\n");
  419.  
  420.         delete reply;
  421.     }
  422. }
  423.  
  424. /*******************************************************************************
  425. ** DoRegisterName
  426. ********************************************************************************/
  427.  
  428. OSStatus DoRegisterName(MapperRef epm)
  429. {
  430.     OSStatus err = kOTNoError;
  431.  
  432.     static char stuff[] = "NBPFreddy:WorkStation@*";
  433.  
  434.     TRegisterRequest    theRequest;
  435.     //
  436.     // We don't want to register the name on any particular address,
  437.     // so let AppleTalk pick one for us.
  438.     //
  439.     theRequest.name.buf    = (UInt8*)stuff;
  440.     theRequest.name.len    = OTStrLength(stuff);
  441.     theRequest.addr.len    = 0;
  442.     
  443.     fprintf(stderr, "Registering NBPFreddy:WorkStation@*\n");
  444.     gErrorAckMsg = kOTNoError;
  445.     gOKAckMsg = NULL;
  446.     
  447.     do
  448.     {    
  449.         err = OTRegisterName(epm, &theRequest, NULL);
  450.  
  451.         if ( err != kOTNoError && err != kOTNoDataErr )
  452.             break;
  453.             
  454.         err = kOTNoError;
  455.     
  456.         while ( gOKAckMsg == NULL && gErrorAckMsg == kOTNoError && !Button() )
  457.             OTIdle();
  458.         
  459.         if ( gErrorAckMsg != kOTNoError )
  460.         {
  461.             err = gErrorAckMsg;
  462.         }
  463.  
  464.         gErrorAckMsg = kOTNoError;
  465.         gOKAckMsg = NULL;
  466.  
  467.     } while ( false );
  468.  
  469.     return err;
  470. }
  471.  
  472. /*******************************************************************************
  473. ** DoDeleteName
  474. ********************************************************************************/
  475.  
  476. OSStatus DoDeleteName(MapperRef epm)
  477. {
  478.     OSStatus err = kOTNoError;
  479.  
  480.     static char stuff[] = "NBPFreddy:WorkStation@*";
  481.  
  482.     TNetbuf theRequest;
  483.     
  484.     theRequest.buf    = (UInt8*)stuff;
  485.     theRequest.len    = OTStrLength(stuff);
  486.     
  487.     fprintf(stderr, "Deleting NBPFreddy:WorkStation@*\n");
  488.     gErrorAckMsg = kOTNoError;
  489.     gOKAckMsg = NULL;
  490.     
  491.     do
  492.     {    
  493.         err = OTDeleteName(epm, &theRequest);
  494.  
  495.         if ( err != kOTNoError && err != kOTNoDataErr )
  496.             break;
  497.             
  498.         err = kOTNoError;
  499.         
  500.         while ( gOKAckMsg == NULL && gErrorAckMsg == kOTNoError && !Button() )
  501.             OTIdle();
  502.         
  503.         if ( gErrorAckMsg != kOTNoError )
  504.         {
  505.             err = gErrorAckMsg;
  506.         }
  507.  
  508.         gErrorAckMsg = kOTNoError;
  509.         gOKAckMsg = NULL;
  510.  
  511.     } while ( false );
  512.  
  513.     return err;
  514. }
  515.  
  516. /*******************************************************************************
  517. ** DoConfirmName
  518. ********************************************************************************/
  519.  
  520. OSStatus DoConfirmName(MapperRef epm)
  521. {
  522.     OSStatus err = kOTNoError;
  523.  
  524.     //
  525.     // name we want to confirm
  526.     //
  527.     static char stuff[] = "Magic Kingdom:WorkStation@*";
  528.  
  529.     TLookupRequest theRequest;    
  530.     
  531.     theRequest.name.buf    = (UInt8*)stuff;
  532.     theRequest.name.len    = OTStrLength(stuff);
  533.     theRequest.maxcnt    = 1;
  534.     theRequest.timeout    = 0;        // Default timeout
  535.  
  536.     //
  537.     // Where we think it is
  538.     //
  539.     DDPAddress    theAddr;
  540.     theAddr.Init(35203,180, 4,  0);     // Of course this is valid only on our network.
  541.     
  542.     theRequest.addr.buf    = (UInt8*)&theAddr;
  543.     theRequest.addr.len    = kDDPAddressLength;
  544.     
  545.     TLookupReply    theReply;
  546.     char            buf[kDDPAddressLength + sizeof(TLookupBuffer) + kNBPEntityBufferSize];
  547.  
  548.     theReply.names.buf        = (UInt8*)buf;
  549.     theReply.names.maxlen    = sizeof(buf);
  550.     
  551.     fprintf(stderr, "Confirming Magic Kingdom:WorkStation@* = 35203, 180, 4,  0\n");
  552.     gErrorAckMsg = kOTNoError;
  553.     gOKAckMsg = NULL;
  554.     
  555.     do
  556.     {    
  557.         err = OTLookupName(epm, &theRequest, &theReply);
  558.     
  559.         if ( err != kOTNoError )
  560.             break;
  561.             
  562.         while ( gOKAckMsg == NULL && gErrorAckMsg == kOTNoError && !Button() )
  563.             OTIdle();
  564.         
  565.         if ( gErrorAckMsg != kOTNoError && gErrorAckMsg != kOTBufferOverflowErr )
  566.         {
  567.             err = gErrorAckMsg;
  568.         }
  569.         else
  570.         {
  571.             if ( theReply.rspcount != 1 )
  572.             {
  573.                 fprintf(stderr, "ERROR: LookupName completed successfully, but rspcount is %d\n",
  574.                         theReply.rspcount);
  575.             }
  576.             else
  577.             {
  578.                 TLookupBuffer*    buf = (TLookupBuffer*)theReply.names.buf;
  579.                 if ( buf->fAddressLength != kDDPAddressLength )
  580.                 {
  581.                     fprintf(stderr, "ERROR: Got back %d for the address length, instead of %d\n",
  582.                             buf->fAddressLength, kDDPAddressLength);
  583.                 }
  584.                 else
  585.                 {
  586.                     DDPAddress* addr = (DDPAddress*)buf->fAddressBuffer;
  587.                     fprintf(stderr, "Confirmed address of %u, %u, %u for \"%s\"\n",
  588.                             addr->GetNetwork(), addr->GetNode(), addr->GetSocket(), stuff);
  589.                 }
  590.             }
  591.         }
  592.  
  593.         gErrorAckMsg = kOTNoError;
  594.         gOKAckMsg = NULL;
  595.  
  596.     } while ( false );
  597.  
  598.     return err;
  599. }
  600.  
  601. /*    -------------------------------------------------------------------------
  602.                     ZIP Demonstration routines
  603.     ------------------------------------------------------------------------- */
  604.  
  605. /*******************************************************************************
  606. ** DoGetLocalZones
  607. ********************************************************************************/
  608.  
  609. OSStatus DoGetLocalZones(TAppleTalkServices* svc)
  610. {
  611.     OSStatus err = kOTNoError;
  612.  
  613.     do
  614.     {
  615.         TNetbuf* theReply = new TNetbuf;
  616.         if ( theReply == NULL )
  617.         {
  618.             fprintf(stderr, "DoGetLocalZones: cannot allocate reply TNetbuf\n");
  619.             break;
  620.         }
  621.         theReply->buf    = incomingReply;
  622.         theReply->maxlen= kMaxReplyBufLen;
  623.         
  624.         fprintf(stderr, "Requesting a LocalZoneList\n");
  625.         gErrorAckMsg = kOTNoError;
  626.         gOKAckMsg = NULL;
  627.  
  628.         err = svc->GetLocalZones(theReply);
  629.     
  630.         if ( err != kOTNoError && err != kOTNoDataErr )
  631.         {
  632.             fprintf(stderr, "DoGetLocalZones: OTGetLocalZones() returns %d\n", err);
  633.         }
  634.         else
  635.         {
  636.             err = kOTNoError;
  637.  
  638.             while ( gOKAckMsg == NULL && gErrorAckMsg == kOTNoError && !Button() )
  639.                 OTIdle();
  640.             
  641.             if ( gErrorAckMsg != kOTNoError )
  642.             {
  643.                 return gErrorAckMsg;
  644.             }
  645.             else if ( gOKAckMsg != NULL )
  646.             {
  647.                 TNetbuf*    zoneList = (TNetbuf*) gOKAckMsg;
  648.                 UInt8*        ptr = zoneList->buf;
  649.                 UInt8*        max = ptr + zoneList->len;
  650.                 fprintf(stderr, "LocalZoneNames returned\n");
  651.         
  652.                 while ( ptr < max )
  653.                 {
  654.                     int cnt = *ptr++;
  655.                     while ( cnt-- != 0 )
  656.                         fprintf(stderr, "%1c", *ptr++);
  657.                     fprintf(stderr, "\n");
  658.                 }
  659.         
  660.                 delete zoneList;
  661.                 gOKAckMsg = NULL;
  662.                 fprintf(stderr,"LocalZoneList Complete!\n");
  663.                 return kOTNoError;
  664.             }
  665.         }
  666.  
  667.     } while ( false );
  668.  
  669.     return err;
  670. }
  671.  
  672. /*******************************************************************************
  673. ** DoGetZoneList
  674. ********************************************************************************/
  675.  
  676. OSStatus DoGetZoneList(TAppleTalkServices* svc)
  677. {
  678.     OSStatus err = kOTNoError;
  679.  
  680.     do
  681.     {
  682.         TNetbuf* theReply = new TNetbuf;
  683.         if ( theReply == NULL )
  684.         {
  685.             fprintf(stderr, "DoGetZoneList: cannot allocate reply TNetbuf\n");
  686.             break;
  687.         }
  688.         theReply->buf    = incomingReply;
  689.         theReply->maxlen= kMaxReplyBufLen;
  690.         
  691.         fprintf(stderr, "Requesting a complete network ZoneList\n");
  692.         gErrorAckMsg = kOTNoError;
  693.         gOKAckMsg = NULL;
  694.  
  695.         err = svc->GetZoneList(theReply);
  696.     
  697.         if ( err != kOTNoError && err != kOTNoDataErr )
  698.         {
  699.             fprintf(stderr, "DoGetZoneList: OTGetZoneList() returns %d\n", err);
  700.         }
  701.         else
  702.         {
  703.             err = kOTNoError;
  704.  
  705.             while ( gOKAckMsg == NULL && gErrorAckMsg == kOTNoError && !Button() )
  706.                 OTIdle();
  707.             
  708.             if ( gErrorAckMsg != kOTNoError )
  709.             {
  710.                 return gErrorAckMsg;
  711.             }
  712.             else if ( gOKAckMsg != NULL )
  713.             {
  714.                 TNetbuf*    zoneList = (TNetbuf*) gOKAckMsg;
  715.                 UInt8*        ptr = zoneList->buf;
  716.                 UInt8*        max = ptr + zoneList->len;
  717.                 
  718.                 fprintf(stderr, "ZoneListNames returned \n");
  719.         
  720.                 while ( ptr < max )
  721.                 {
  722.                     int cnt = *ptr++;
  723.                     while ( cnt-- != 0 )
  724.                         fprintf(stderr, "%1c", *ptr++);
  725.                     fprintf(stderr, "\n");
  726.                 }
  727.         
  728.                 delete zoneList;
  729.                 gOKAckMsg = NULL;
  730.                 fprintf(stderr,"ZoneList Complete!\n");
  731.                 return kOTNoError;
  732.             }
  733.         }
  734.  
  735.     } while ( false );
  736.  
  737.     return err;
  738. }
  739.  
  740. /*******************************************************************************
  741. ** DoGetNetInfo
  742. ********************************************************************************/
  743.  
  744. OSStatus DoGetNetInfo(TAppleTalkServices* svc)
  745. {
  746.     OSStatus err = kOTNoError;
  747.  
  748.     do
  749.     {
  750.         TNetbuf* theReply = new TNetbuf;
  751.         if ( theReply == NULL )
  752.         {
  753.             fprintf(stderr, "DoGetNetInfo: cannot allocate reply TNetbuf\n");
  754.             break;
  755.         }
  756.         theReply->buf    = incomingReply;
  757.         theReply->maxlen= kMaxReplyBufLen;
  758.         
  759.         fprintf(stderr, "Requesting ATalk Info\n");
  760.         gErrorAckMsg = kOTNoError;
  761.         gOKAckMsg = NULL;
  762.  
  763.         err = svc->GetInfo(theReply);
  764.     
  765.         if ( err != kOTNoError && err != kOTNoDataErr )
  766.         {
  767.             fprintf(stderr, "DoGetNetInfo: OTGetATalkInfo() returns %d\n", err);
  768.         }
  769.         else
  770.         {
  771.             err = kOTNoError;
  772.  
  773.             while ( gOKAckMsg == NULL && gErrorAckMsg == kOTNoError && !Button() )
  774.                 OTIdle();
  775.             
  776.             if ( gErrorAckMsg != kOTNoError )
  777.             {
  778.                 return gErrorAckMsg;
  779.             }
  780.             else if ( gOKAckMsg != NULL )
  781.             {
  782.                 TNetbuf* reply = (TNetbuf*) gOKAckMsg;
  783.                 AppleTalkInfo* info = (AppleTalkInfo*) reply->buf;
  784.         
  785.         
  786.                 fprintf(stderr, "Our Address= ");
  787.                 ShowDDPAddress(&(info->fOurAddress));
  788.                 fprintf(stderr, "\n");
  789.  
  790.                 if ( info->fFlags & kATalkInfoHasRouter )
  791.                 {
  792.                     fprintf(stderr, "Local Router Address= ");
  793.                     ShowDDPAddress(&(info->fRouterAddress));
  794.                     fprintf(stderr, "\n");
  795.                 }
  796.         
  797.                 fprintf(stderr, "Cable Range, LOW = $%04X, HIGH = $%04X\n",
  798.                         info->fCableRange[0], info->fCableRange[1]);
  799.  
  800.                 fprintf(stderr, "Flags returned= ");
  801.                 if ( info->fFlags & kATalkInfoIsExtended )
  802.                 {
  803.                     fprintf(stderr, "IsExtended ");
  804.                 }
  805.                 if ( info->fFlags & kATalkInfoHasRouter )
  806.                 {
  807.                     fprintf(stderr, "HasRouter ");
  808.                 }
  809.                 fprintf(stderr, "\n");
  810.                 
  811.                 delete reply;
  812.                 gOKAckMsg = NULL;
  813.                 fprintf(stderr,"NetInfo Request Complete!\n");
  814.                 return kOTNoError;
  815.             }
  816.         }
  817.  
  818.     } while ( false );
  819.  
  820.     return err;
  821.  
  822. }
  823.  
  824. /*******************************************************************************
  825. ** DoGetMyZoneReq  
  826. ********************************************************************************/
  827.  
  828. OSStatus DoGetMyZoneReq(TAppleTalkServices* svc)
  829. {
  830.     OSStatus err = kOTNoError;
  831.  
  832.     do
  833.     {
  834.         TNetbuf* theReply = new TNetbuf;
  835.         if ( theReply == NULL )
  836.         {
  837.             break;
  838.         }
  839.         theReply->buf    = incomingReply;
  840.         theReply->maxlen= kMaxReplyBufLen;
  841.         
  842.         fprintf(stderr, "Requesting current zone name\n");
  843.         gErrorAckMsg = kOTNoError;
  844.         gOKAckMsg = NULL;
  845.  
  846.         err = svc->GetMyZone(theReply);
  847.     
  848.         if ( err != kOTNoError && err != kOTNoDataErr )
  849.         {
  850.             fprintf(stderr, "DoGetMyZoneReq: OTGetMyZone() returns %d\n", err);
  851.         }
  852.         else
  853.         {
  854.             err = kOTNoError;
  855.  
  856.             while ( gOKAckMsg == NULL && gErrorAckMsg == kOTNoError && !Button() )
  857.                 OTIdle();
  858.             
  859.             if ( gErrorAckMsg != kOTNoError )
  860.             {
  861.                 return gErrorAckMsg;
  862.             }
  863.             else if ( gOKAckMsg != NULL )
  864.             {
  865.                 TNetbuf* myZone = (TNetbuf*)gOKAckMsg;
  866.                 int cnt = myZone->len;
  867.                 unsigned char* ptr = myZone->buf;
  868.                 fprintf(stderr, "MyZoneName returned= ");
  869.                 while ( cnt-- != 0 )
  870.                     fprintf(stderr, "%1c", *(ptr++));
  871.                 fprintf(stderr, "\n");
  872.         
  873.                 delete myZone;
  874.                 gOKAckMsg = NULL;
  875.                 fprintf(stderr,"MyZoneName Complete!\n");
  876.                 return kOTNoError;
  877.             }
  878.         }
  879.  
  880.     } while ( false );
  881.  
  882.     return err;
  883. }
  884.  
  885.  
  886. /*******************************************************************************
  887. ** 
  888. ********************************************************************************/
  889.  
  890. /*    -------------------------------------------------------------------------
  891.                     Main Program
  892.     ------------------------------------------------------------------------- */
  893.  
  894. /*******************************************************************************
  895. ** DoTest
  896. ********************************************************************************/
  897.  
  898. void DoTest()
  899. {
  900.     OSStatus    err = kOTNoError;
  901.     EndpointRef    ep    = kOTInvalidEndpointRef;
  902.  
  903.     do
  904.     {
  905.         //
  906.         // Now create a DDP
  907.         //
  908.         ep = OTOpenEndpoint(OTCreateConfiguration(kDDPName), 0, NULL, &err);
  909.  
  910.         if ( ep == kOTInvalidEndpointRef || err != kOTNoError )
  911.         {
  912.             ep = kOTInvalidEndpointRef;
  913.             fprintf(stderr,"ERROR: OpenEndpoint(\"DDP\") failed with %d\n", err);
  914.             break;
  915.         }
  916.         //
  917.         // Install notifier we're going to use for testing
  918.         //
  919.         OTInstallNotifier(ep, HandleEndpointEvents, &gNotifyFlag);
  920.         OTSetSynchronous(ep);
  921.  
  922.         ShowFullEndpointData(ep);
  923.  
  924.         //
  925.         // Try to bind
  926.         // 
  927.         OTSetSynchronous(ep);
  928.         fprintf(stderr, "About to Bind()\n");
  929.         err = BindDDPEndpoint(ep);
  930.         if ( err != kOTNoError )
  931.             break;        
  932.  
  933.         //
  934.         // Send out and echo request
  935.         // 
  936.         OTSetAsynchronous(ep);
  937.         fprintf(stderr, "About to Send some data\n");
  938.         err = DoSend(ep);
  939.         if ( err != kOTNoError )
  940.             break;
  941.  
  942.         //
  943.         // Wait a bit (1/4 second)
  944.         //
  945.         {
  946.             OTTimeStamp    stamp;
  947.             OTGetTimeStamp(&stamp);
  948.             while ( OTElapsedMilliseconds(&stamp) < 250 )
  949.                 OTIdle();
  950.         }
  951.  
  952.         //
  953.         // Make sure we're non-blocking so the reads will not wait for data to
  954.         // come in.
  955.         //
  956.         OTSetNonBlocking(ep);
  957.         OTSetSynchronous(ep);
  958.         
  959.         while ( (err = ReadData(ep)) == kOTNoError )
  960.         {
  961.             if (Button())
  962.                 break;
  963.         }
  964.  
  965.         OTIdle();
  966.  
  967.         OTSetBlocking(ep);
  968.  
  969.         //
  970.         // Try to Unbind
  971.         // 
  972.         fprintf(stderr, "About to Unbind()\n");
  973.         err = OTUnbind(ep);
  974.         if ( err != kOTNoError )
  975.         {
  976.             fprintf(stderr, "ERROR: Unbind() returned %d\n", err);
  977.             break;
  978.         }
  979.  
  980.     } while ( false );
  981.  
  982.     //
  983.     // Get rid of endpoint.
  984.     //
  985.     if ( ep != NULL )
  986.     {
  987.         OTRemoveNotifier(ep);
  988.         OTCloseProvider(ep);
  989.     }
  990.  
  991. /*    -------------------------------------------------------------------------
  992.         Now Demonstrate a TMapper (NBP stuff)
  993.     ------------------------------------------------------------------------- */
  994.  
  995.     MapperRef    mapper = kOTInvalidMapperRef;
  996.     
  997.     do
  998.     {
  999.         //
  1000.         // Now create a NBP-based TMapper
  1001.         //
  1002.         mapper = OTOpenMapper(OTCreateConfiguration(kNBPName), 0, &err);
  1003.     
  1004.         if ( mapper == kOTInvalidMapperRef || err != kOTNoError )
  1005.         {
  1006.             mapper = kOTInvalidMapperRef;
  1007.             fprintf(stderr,"ERROR: new of NBP mapper failed.\n");
  1008.             break;
  1009.         }
  1010.         //
  1011.         // Install notifier we're going to use for testing
  1012.         //
  1013.         err = OTInstallNotifier(mapper, HandleMapperEvents, NULL);
  1014.         if ( err != kOTNoError )
  1015.         {
  1016.             fprintf(stderr, "ERROR: InstallNotifier() failed with %d\n", err);
  1017.             break;
  1018.         }
  1019.         OTSetAsynchronous(mapper);
  1020.     
  1021.         do
  1022.         {
  1023.     
  1024.         /*    -------------------------------------------------------------------------
  1025.             Register an NBP Name...currently "NBPFreddy:WorkStation@*"
  1026.             ------------------------------------------------------------------------- */
  1027.         
  1028.             err = DoRegisterName(mapper);
  1029.             if ( err != kOTNoError )
  1030.             {
  1031.                 fprintf(stderr, "DoRegisterName returned %d\n", err);
  1032.                 break;
  1033.             }
  1034.         
  1035.             fprintf(stderr, "Name Registration complete…click mouse to exit!\n");
  1036.         
  1037.             while ( !Button() )                    // Wait for 'um to press mouse button
  1038.                 ;
  1039.             while ( Button() )                    // Wait for 'um to remove their grubby paws!
  1040.                 ;
  1041.         
  1042.         /*    -------------------------------------------------------------------------
  1043.             Perform an NBP lookup...requesting 10 replies (unless you change it)
  1044.             ------------------------------------------------------------------------- */
  1045.     
  1046.             gLkUpReplies = 10;        
  1047.         
  1048.             //
  1049.             // Send Lookup request
  1050.             //
  1051.             DoSendLkUpReq(gLkUpReplies, mapper);
  1052.     
  1053.             //
  1054.             // Show the replies
  1055.             //
  1056.             DoReadLkUpReplies();
  1057.         
  1058.         /*    -------------------------------------------------------------------------
  1059.             Delete our registered NBP Name
  1060.             ------------------------------------------------------------------------- */
  1061.         
  1062.             err = DoDeleteName(mapper);
  1063.             if ( err != kOTNoError )
  1064.             {
  1065.                 fprintf(stderr, "DoDeleteName returned %d\n", err);
  1066.                 break;
  1067.             }
  1068.         
  1069.         
  1070.         /*    -------------------------------------------------------------------------
  1071.             Confirm an NBP Name to address mapping
  1072.             ------------------------------------------------------------------------- */
  1073.         
  1074.             err = DoConfirmName(mapper);
  1075.             if ( err != kOTNoError )
  1076.             {
  1077.                 fprintf(stderr, "DoConfirmName returned %d\n", err);
  1078.                 break;
  1079.             }
  1080.         
  1081.             fprintf(stderr, "Name Confirmation complete…click mouse to exit!\n");
  1082.         
  1083.             while ( !Button() )                    // Wait for 'um to press mouse button
  1084.                 ;
  1085.             while ( Button() )                    // Wait for 'um to remove their grubby paws!
  1086.                 ;
  1087.     
  1088.             } while ( false );
  1089.  
  1090.     } while ( false );
  1091.  
  1092.     //
  1093.     // Get rid of TMapper.
  1094.     //
  1095.     if ( mapper != NULL )
  1096.     {
  1097.         OTRemoveNotifier(mapper);
  1098.         OTCloseProvider(mapper);
  1099.     }
  1100.  
  1101. /*    -------------------------------------------------------------------------
  1102.         Now Demonstrate a AppleTalkSvc (Zones, etc.)
  1103.     ------------------------------------------------------------------------- */
  1104.  
  1105.     TAppleTalkServices* svc = NULL;
  1106.  
  1107.     do
  1108.     {
  1109.         //
  1110.         // Now create a ZIP
  1111.         //
  1112.         svc = OTOpenAppleTalkServices(kDefaultAppleTalkServicesPath, 0, &err);
  1113.     
  1114.         if ( svc == NULL || err != kOTNoError )
  1115.         {
  1116.             svc = NULL;
  1117.             fprintf(stderr,"ERROR: open of ZIP ATalkSvc failed.\n");
  1118.         }
  1119.  
  1120.         //
  1121.         // Install notifier we're going to use
  1122.         //
  1123.         err = svc->InstallNotifier(HandleServicesEvents, NULL);
  1124.         if ( err != kOTNoError )
  1125.         {
  1126.             fprintf(stderr, "ERROR: InstallNotifier() failed with %d\n", err);
  1127.             break;
  1128.         }
  1129.         svc->SetAsynchronous();
  1130.  
  1131. /*        -------------------------------------------------------------------------
  1132.         Perform a ZIP GetZoneList.
  1133.         ------------------------------------------------------------------------- */
  1134.  
  1135.         do
  1136.         {
  1137.             //
  1138.             // Send data
  1139.             //
  1140.             err = DoGetZoneList(svc);
  1141.             if ( err != kOTNoError )
  1142.             {
  1143.                 fprintf(stderr, "DoGetZoneList returned %d\n", err);
  1144.                 break;
  1145.             }
  1146.  
  1147.         } while ( false );
  1148.  
  1149. /*        -------------------------------------------------------------------------
  1150.         Issue a ZIP GetMyZoneName.
  1151.         ------------------------------------------------------------------------- */
  1152.  
  1153.         err = DoGetMyZoneReq(svc);
  1154.         if ( err != kOTNoError )
  1155.         {
  1156.             fprintf(stderr, "DoGetMyZoneReq returned %d\n", err);
  1157.             break;
  1158.         }
  1159.  
  1160. /*        -------------------------------------------------------------------------
  1161.         Issue a ZIP GetNetInfo.
  1162.         ------------------------------------------------------------------------- */
  1163.  
  1164.         err = DoGetNetInfo(svc);
  1165.         if ( err != kOTNoError )
  1166.         {
  1167.             fprintf(stderr, "DoGetNetInfoReq returned %d\n", err);
  1168.             break;
  1169.         }
  1170.  
  1171. /*        -------------------------------------------------------------------------
  1172.         Perform a ZIP GetLocalZones.
  1173.         ------------------------------------------------------------------------- */
  1174.  
  1175.         do
  1176.         {
  1177.             //
  1178.             // Send data
  1179.             //
  1180.             err = DoGetLocalZones(svc);
  1181.             if ( err != kOTNoError )
  1182.             {
  1183.                 fprintf(stderr, "DoGetLocalZones returned %d\n", err);
  1184.                 break;
  1185.             }
  1186.     
  1187.         } while ( false );
  1188.  
  1189.     } while ( false );
  1190.  
  1191.     //
  1192.     // Get rid of AppleTalkSvc.
  1193.     //
  1194.     if ( svc != NULL )
  1195.     {
  1196.         svc->RemoveNotifier();
  1197.         svc->Close();
  1198.     }
  1199. }
  1200.  
  1201. /*******************************************************************************
  1202. ** Initialize Open Transport and call DoTest function
  1203. ********************************************************************************/
  1204.  
  1205. main(int, char**) 
  1206. {
  1207.     InitGraf(&qd.thePort);                    // initialize quickdraw so we can use regions
  1208.  
  1209.     fprintf(stderr, "DDPSample showing usage of DDP, Mapper object,\n");
  1210.     fprintf(stderr, "and the AppleTalk services object.\n\n");
  1211.     //
  1212.     // Initialize Open Transport
  1213.     //
  1214.     InitOpenTransport();
  1215.         
  1216.     //
  1217.     // Run the test
  1218.     //
  1219.     DoTest();
  1220.     
  1221.     //
  1222.     // Close down Open Transport.
  1223.     // Not strictly necessary since it patches _ExitToShell and will
  1224.     // clean us up anyway.
  1225.     //
  1226.     CloseOpenTransport();
  1227.         
  1228.     fprintf(stderr, "\n\nDone\n");
  1229.         
  1230.     return 0;
  1231. };
  1232.